<template>
    <el-popover :placement="placement" :width="popoverWidth" :visible="visible">  
        <template #reference>
            <div :class="['stage-subject','sss', ssClass]" @click="toggle" ref="inputStageWrapper">
                <div class="ss">
                    <template v-if="isHasData">
                        <div class="ss-stage"
                            v-for="(item, stageIndex) in stateData.resultToSubmit"
                            :key="item.stageId">
                            <div class="ss-stagename ss-bold">{{ item.stageName + '：'}}</div>
                            <div class="ss-subjects">
                                <span class="ss-subject"
                                    v-for="(subject, subjectIndex) in item.subjectList"
                                    :key="subject.subjectId">
                                    {{ subject.subjectName }}
                                    <i class="stage-icon-guanbi"
                                        @click.stop="delSubject(stageIndex, subjectIndex, item.stageId, subject.subjectId)"></i>
                                </span>
                            </div>
                        </div>
                    </template>
                    <div class="placeholder"
                        v-else>{{ props.placeholder }}</div>
                </div>
                <i class="stage-icon-clear" v-if="stateData.resultToSubmit.length" @click.stop="resetCommit"></i>
            </div>
        </template>
            <div ref="selectStageWrapper">
                <div class="sss-list-inner" :style="{'max-height': maxHeight}">
                    <!-- 左边部分所有学段数据 -->
                    <div class="stages">
                        <div :class="['stage', fmtStageClass(item.stage)]"
                            v-for="item in stateData.stages"
                            :key="item.stage"
                            @click="checkStage(item)">
                            <div class="stage-name">
                                {{item.stageName}}
                            </div>
                            <div class="selected-num"
                                v-if="stateData.stageNumMap[item.stage]">{{ stateData.stageNumMap[item.stage] }}</div>
                        </div>
                    </div>
                     <!-- 右边部分学段对应的学科、年级数据 -->
                    <div class="subjects">
                        <div class="subject">
                            <el-checkbox v-model="isAllCheckedSubject"
                                @change="selectAll($event)">全学科</el-checkbox>
                        </div>
                        <div class="subjects-inner">
                            <div class="subject"
                                v-for="subject in stateData.stageSubjectMap[curStage]"
                                :key="`${curStage}-${subject.code}`">>
                                <el-checkbox v-model="subject.checked" 
                                    @change="changeChecked($event, subject)">{{ subject.name }}</el-checkbox>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="btns">
                    <div class="btn btn-reset"
                        @click="toggle">取消</div>
                    <div class="btn btn-confirm"
                        @click="confirm">确定</div>
                </div>
            </div>
    </el-popover>
</template>

<script setup>
import { onMounted, ref, reactive, nextTick, computed, unref, onBeforeUnmount, watch } from 'vue'
import { useStore } from 'vuex';


const store = useStore();

// update:selectedData 格式与props的selectedData格式一致
const emit = defineEmits(['update:selectedData']);

const visible = ref(false);

const isInit = ref(true);// 是否是初始化进来

// 输入框
const inputStageWrapper = ref(null);

// 下拉内容
const selectStageWrapper = ref(null);


const props = defineProps({
    placeholder: {
        type: String,
        default: '请选择学段学科'
    },
    maxHeight: {// 400px
        type: String,
        default: 'auto'
    },
    selectedData: {// 回显数据
        type: Array,
        default: () => {
            return [];
        //    return [{
        //             stageCode: 1202,
        //             stageName: '小学',
        //             subjectCode: '1102',
        //             subjectName: '语文'
        //          }]
        }
    },
    list: { // 学段学科初始化数据
        type: Array,
        default: () => {
            return []
        }
    },
    placement: { // 出现的位置
        type: String,
        default: 'bottom'
    }
})

const data = ref({}); // 下拉需要渲染数据

const curStage = ref('')// 下拉激活的学段

const popoverWidth = ref(600);// 默认的宽度

const stateData = reactive({
    basicData: [], // 接口返回的初始数据
    stages: [], // 所有学段数据-排序
    stageNameMap: {}, // 所有学段对象数据
    resultToSubmit: [], // 文本框需要提交的数据
    commitResult: [], // 组装好的需要提交的数据
    initSelectData: [], // 初始化的选中数据
    stageSubjectMap: {}, // 学段学科数据
    stageNumMap: {} // 学段对应的选中的学科年级数据  subjectNum + gradeNum
  
})

watch(() => props.selectedData, (n = []) => {
    stateData.initSelectData = n;
     // 组装输入框中已经选中的所有数据
    stateData.resultToSubmit = n;
    // 组装提交给后台的数据
    stateData.commitResult = n; 

}, {
    deep: true
})

// 样式
const ssClass = computed(() => {
    return !stateData.resultToSubmit || !stateData.resultToSubmit.length && 'sss-no-padding' || ''
})


// 判断是否有数据
const isHasData = computed(() => {
    return stateData.resultToSubmit && stateData.resultToSubmit.length
})

function fmtStageClass (stageId) {
    return stageId == curStage.value && 'cur-stage' || ''
}


// 计算学科是否全选
const isAllCheckedSubject = computed({
    get() {
        let num = stateData.stageNumMap[curStage.value]
        return num && num === stateData.stageSubjectMap[curStage.value].length || false;
    },
    set(val) {
        let num = stateData.stageNumMap[curStage.value]
        return num && num === stateData.stageSubjectMap[curStage.value].length || false;
    }
})



function getData () {
    // 获取学段学科年级列表
    return store.dispatch('common/getStageRefSubject').then((res) => {
        refreshData(res);
    }).catch(err => {
        console.log(err);
    }).finally(() => {
    });
}

function refreshData(res) {
    stateData.basicData = res || [];
    curStage.value = stateData.basicData.length && stateData.basicData[0] && stateData.basicData[0].stage || '';
    fmtInitData();
    fmtCheckedData();
}

// 组装所有学段与学科对象数据  stageId:[学科]
// 组装所有学段与年级对象数据  stageId:[年级]
function fmtInitData() {
    let list = stateData.basicData.length && stateData.basicData || [];
    // 学段数据
    let stageList = [];

    list.length && list.forEach(item => {
        let temp = {stage: item.stage, stageName: item.stageName}
        stageList.push(temp);
        stateData.stageNameMap[item.stage] = temp;
        stateData.stageSubjectMap[item.stage] = item.subjects || [];
    })
    stateData.stages = stageList;
}

async function confirmData () {
    let stageList = stateData.stageNumMap && Object.keys(stateData.stageNumMap) || [];
    let result = [], index = -1;
    let commitResult = [];
    stageList.length && stageList.forEach((stageId) => {
        if (stateData.stageNumMap[stageId]) {
            let stageTemp = stateData.stageNameMap[stageId] || {};
            index++;
            result.push({
                stageId: stageId,
                stageName: stageTemp.stageName,
                subjectList: [],
                gradeList: []
            });
            let subjectList = stateData.stageSubjectMap[stageId] || [];

            subjectList.forEach(subject => {
                if (subject.checked) {
                    let temp = {subjectCode: subject.code, subjectName: subject.name, stageCode: stageId, stageName: stageTemp.stageName}
                    commitResult.push(temp);
                    result[index].subjectList.push({
                        subjectId: subject.code,
                        subjectName: subject.name
                    });
                }
            });
        }
    });

    console.log('commitResult==', commitResult);

    stateData.resultToSubmit = result;
    stateData.commitResult = commitResult;

    if(!isInit.value){
         emit('update:selectedData', stateData.commitResult);
    }

}

// 切换学段
function checkStage(item){
    curStage.value = item.stage;
}

// 初始化组装已经选中的数据
function fmtCheckedData () {
    let checkedList = stateData.initSelectData || [];

    let selectMap = {};
    let checkedStageList = [];
    let selectSubjectObj = {};

    reset();
    
    checkedList.length && checkedList.forEach(item => {
        if(!selectMap[item.stageCode]){
            stateData.stageNumMap[item.stageCode] = 1;
            checkedStageList.push({stageId: item.stageCode, stageName: item.stageName, subjectList: []});
            selectMap[item.stageCode] = [item];
         }else{
            ++stateData.stageNumMap[item.stageCode];
            selectMap[item.stageCode].push(item);
        }
        let mainId = `${item.stageCode}-${item.subjectCode}`;
        selectSubjectObj[mainId] = item;
    });

    checkedStageList.length && checkedStageList.forEach(item => {
        item.subjectList = selectMap[item.stageId] || [];
        let subjectList = stateData.stageSubjectMap[item.stageId] || [];
        subjectList.length && subjectList.forEach(subjectItem => {
            let mainId = `${item.stageId}-${subjectItem.code}`;
            if(selectSubjectObj[mainId]) {
                subjectItem.checked = true;
            }
        });
    })

    // 组装输入框中已经选中的所有数据
    stateData.resultToSubmit = checkedStageList || [];
    // 组装提交给后台的数据
    stateData.commitResult = checkedList; 
}


// 点击打开对话框
function toggle () {
    isInit.value = false;
    nextTick(() => {
        let sssList = document.querySelector('.stage-subject');
        popoverWidth.value = sssList.offsetWidth - 28;
        visible.value = !visible.value;
        if(visible.value) {
            fmtCheckedData();
        }
    })
}

function close () {
    isInit.value = false;
    visible.value = false;
}

// 删除学科单个元素数据
function delSubject (stageIndex, subjectIndex, stageId, subjectId) {
    stateData.resultToSubmit[stageIndex].subjectList.splice(subjectIndex, 1);
    if (!stateData.resultToSubmit[stageIndex].subjectList.length) {
        stateData.resultToSubmit.splice(stageIndex, 1);
    }
    let subjectList = stateData.stageSubjectMap[stageId] || [];
    
    subjectList.length && subjectList.forEach(subjectItem => {
        if(subjectItem.code === subjectId) {
            subjectItem.checked = false;
            --stateData.stageNumMap[stageId];
        }
    })

    stateData.commitResult = stateData.commitResult.filter(item => {
         if(item.stageCode !== stageId || item.subjectCode !== subjectId) {
             return item;
         }
    });
    
    console.log('commitResult==', stateData.commitResult);
    emit('update:selectedData', stateData.commitResult);
}



// 选择学科、年级数据
function changeChecked (e, subject) {
    subject.checked = e;
    // debugger
    if(stateData.stageNumMap[curStage.value]) {
        e ? ++stateData.stageNumMap[curStage.value] : --stateData.stageNumMap[curStage.value];
    }else{
        stateData.stageNumMap[curStage.value] = e ? 1 : 0;
    }
}

// 全选/全取消 学段
function selectAll (e) {
    if (curStage.value == 9999) {
        for (let item in stateData.stageList) {
            setStage(e, item.stage);
        }
    } else {
        setStage(e, curStage.value);
    }
}

function setStage (selected, stageId) {
    let list = stateData.stageSubjectMap[stageId] || [];
    list.length && list.forEach(item => {
        item.checked = selected;
    })
    stateData.stageNumMap[stageId] = selected ? list.length : 0;
}

// 确认
function confirm () {
    confirmData();
    toggle();
}


// 重置
function reset () {
    isInit.value = true;
    stateData.initSelectData = [];
    fmtInitData();
     // 组装输入框中已经选中的所有数据
    stateData.resultToSubmit =[];
    // 组装提交给后台的数据
    stateData.commitResult = [];
}

// 清空
function resetCommit() {
    reset();
    visible.value = false;
    emit('update:selectedData', stateData.commitResult);
}


// 关闭对话框
function closePopover(){
    visible.value = false;
}


// // watch区
// watch(() => props.selectedData, (val) => {
//      console.log(3333, val);
// });

onMounted(async () => {
    // 请求学段学科
    // 请求学段学科
    if(props.list && props.list.length) {
        refreshData(props.list);
    }else{
        getData();
    }
    isInit.value = true;
    stateData.initSelectData = props.selectedData.length && JSON.parse(JSON.stringify(props.selectedData)) || []

    await nextTick();
    // 初始化弹框宽度
    let sssList = document.querySelector('.stage-subject');
    popoverWidth.value = sssList.offsetWidth - 28;
    
    window.addEventListener('mousedown', mousedownChange, true); // 监听鼠标点击事件
})



const mousedownChange = (e) => {
    if(unref(inputStageWrapper).contains(e.target) || unref(selectStageWrapper).contains(e.target)){
         return;
    }
    closePopover();
}

onBeforeUnmount(() => {
    window.removeEventListener('mousedown', mousedownChange, true);
});

</script>

<style lang="scss">
.subject{
    .el-checkbox__label{
        height: 20px;
        font-size: 14px;
        font-family: PingFangSC-Regular, PingFang SC;
        font-weight: 400;
        color: #666666;
        line-height: 20px;
    }
}
</style>

<style lang="scss" scoped>
$primaryColor: var(--color-primary);
$primaryOpacityColor1: #EDF4FF;
$borderHoverColor: var(--el-border-color-hover);
$placeholderColor: var(--el-text-color-placeholder);

.sss {
    min-height: 30px;
    height: auto;
    width: 100%;
    border: 1px solid #CCCCCC;
    padding: 0px 0px 0px 12px;
    position: relative;
    border-radius: 4px;
    box-sizing: border-box;
    &:hover {
        border-color: $borderHoverColor;
    }
    &.sss-no-padding {
        padding: 0px 0px 0px 12px;
    }
    .placeholder {
        color: $placeholderColor;
        cursor: pointer;
        user-select: none;
    }
    .icon-clear{
        color: #B9BECE;
        font-size: 14px;
        display: inline-block;
        transition: all 0.2s;
        margin: 0px 8px;
        position: absolute;
        opacity: 0;
        cursor: pointer;
    }
    &:hover{
        .icon-clear{
            opacity: 1;
        }
    }
}
.ss {
    width: calc(100% - 30px);
    color: #000000;
    line-height: 30px;
    display: inline-block;

    .ss-stage {
        display: flex;
        align-items: baseline;
        margin-bottom: 4px;
        &:last-child {
            margin-bottom: 0;
        }
    }

    .ss-stageback {
        .ss-back {
           display: flex;
           align-items: baseline;
        }
       
    }
    .ss-stagename {
        font-size: 14px;
        font-family: PingFangSC-Medium, PingFang SC;
        font-weight: 400;
        color: #535A73;
        flex: 0 0 56px;
        &.ss-bold {
            font-weight: bold;
        }
    }
    .ss-subjects {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        min-width: 100px;
    }
    .ss-subject {
        background: #ECEFF4;
        border-radius: 4px;
        padding: 1px 6px;
        margin: 0 8px 6px 0;
        height: 20px;
        font-size: 14px;
        font-family: PingFangSC-Regular, PingFang SC;
        font-weight: 400;
        color: #535A73;
        line-height: 20px;
    }
}

.sss-list {
    position: absolute;
    top: 41px;
    left: 0px;
    width: 100%;
    background: #ffffff;
    box-shadow: 0px 1px 6px 0px rgba(51, 61, 92, 0.2);
    border-radius: 2px;
    z-index: 1;
    display: none;
}
.btns {
    border-top: 1px solid #f0f0f0;
    padding: 12px 0px 0px;
    text-align: right;
}
.btn{
    border-radius: 2px;
    display: inline-block;
    cursor: pointer;
    user-select: none;
    padding:4px 18px;
    font-size: 14px;
    font-family: PingFangSC-Regular, PingFang SC;
    font-weight: 400;
}
.btn-reset {
    border: 1px solid #DDDDDD;
    color: #666666;
    margin-right:12px;
}
.btn-confirm {
    border: 1px solid $primaryColor;
    color: #ffffff;
    background: $primaryColor
}
.sss-list-inner {
    display: flex;
    align-items: stretch;
    max-height: 150px;
}
.stages {
    flex: 0 0 100px;
    padding-right: 11px;
    border-right: 1px solid #eeeeee;
    overflow-y: auto;
}
.stage {
    height: 28px;
    width: 100%;
    line-height: 28px;
    color: #000000;
    cursor: pointer;
    user-select: none;
    padding: 0 8px;
    box-sizing: border-box;
    margin-bottom: 10px;
    font-size: 14px;
    font-family: PingFangSC-Regular, PingFang SC;
    position: relative;
    &.cur-stage {
        color: $primaryColor;
        position: relative;
        background: $primaryOpacityColor1;
        border-radius:4px;
        color:$primaryColor;
    }
}
.subjects {
    padding: 4px 4px 0 16px;
    overflow-y: auto;
}
.subject {
    display: inline-block;
    margin-right: 16px;
    height: 32px;
    &.mtop {
        margin-top: 20px;
    }
}
.stage-name {
    display: inline-block;
    line-height: 28px;
}
.selected-num {
    font-size: 10px;
    color: #fff;
    background: $primaryColor;
    display: inline-block;
    padding: 0px 5px;
    height: 14px;
    line-height: 14px;
    text-align: center;
    border-radius: 14px;
    margin-left:4px;
}

.stage-icon-guanbi {
    background: url(./assets/close.png) no-repeat;
    width: 10px;
    height: 10px;
    background-size: contain;
    display: inline-block;
    cursor: pointer;
}
.stage-icon-clear {
    background: url(./assets/clear.png) no-repeat;
    width: 14px;
    height: 14px;
    background-size: contain;
    display: inline-block;
    cursor: pointer;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}
</style>